package exp5;

// import com.sun.corba.se.impl.orbutil.ObjectUtility;

//---------------------------------------------------------------
//  SocketClient_5.java   Author: 唐才铭   Date：2018-06-13
//
//  基于Java Socket实现客户端功能，传输方式用TCP
//  客户端让用户输入中缀表达式，然后把中缀表达式调用MyBC.java的
//  功能转化为后缀表达式，把后缀表达式用3DES或AES算法加密通过网络把密文和明文的MD5値发送给服务器;
//  客户端和服务器用DH算法进行3DES或AES算法的密钥交换;
//  显示服务器发送过来的结果。
//---------------------------------------------------------------

import javax.crypto.KeyAgreement;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.net.Socket;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Scanner;


/**
 * Created by tcm on 2018/6/13.
 */
public class SocketClient_5 {
    public static void main(String[] args) throws IOException {
        //1.建立客户端Socket连接，指定服务器位置和端口
        //  Socket socket = new Socket("localhost",8080);
        Socket socket = new Socket("192.168.1.155",8800);

        //2.得到socket读写流
        OutputStream outputStream = socket.getOutputStream();
        //  PrintWriter printWriter = new PrintWriter(outputStream);
        OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
        //输入流
        InputStream inputStream = socket.getInputStream();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream,"UTF-8"));
        //3.利用流按照一定的操作，对socket进行读写操作

        //客户端让用户输入中缀表达式，然后把中缀表达式调用MyBC.java的功能转化为后缀表达式
        String a1,a2,a3,a4;
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入中缀表达式");
        String info1 = scanner.nextLine();
        info1 = MyBC.infixToSuffix(info1);  // 转后缀
        a1 = info1 + "###";
        String suffix = new String(a1.getBytes("GBK"),"utf-8");
        outputStreamWriter.write(suffix);
        outputStreamWriter.flush();
        String cleartext = "",ciphertext = "";

        //把后缀表达式用3DES或AES算法加密后通过网络把密文和明文的MD5値发送给服务器
        try {
             cleartext = DigestPass.MD5(info1); // 明文MID5
            a2 = cleartext + "###";
            String info_cleartext = new String(a2.getBytes("GBK"),"utf-8");
            outputStreamWriter.write(info_cleartext);
            outputStreamWriter.flush();
            info1 = SEnc.encrypt(info1);  // 加密
            a3 = info1 + "###";
            String encrypt = new String(a3.getBytes("GBK"),"utf-8");
            outputStreamWriter.write(encrypt);
            outputStreamWriter.flush();
             ciphertext = DigestPass.MD5(info1); // 密文MID5


        } catch (Exception e) {
            e.printStackTrace();
        }

        // 客户端和服务器用DH算法进行3DES或AES算法的密钥交换
        try{
            // 读取对方的DH公钥
            FileInputStream f1=new FileInputStream("Bpub.dat");
            ObjectInputStream b1=new ObjectInputStream(f1);
            PublicKey  pbk=(PublicKey)b1.readObject( );
            //读取自己的DH私钥
            FileInputStream f2=new FileInputStream("Apri.dat");
            ObjectInputStream b2=new ObjectInputStream(f2);
            PrivateKey  prk=(PrivateKey)b2.readObject( );
            // 执行密钥协定
            KeyAgreement ka=KeyAgreement.getInstance("DH");
            ka.init(prk);
            ka.doPhase(pbk,true);
            System.out.println("\n" + "公钥为:");
            //生成共享信息
            byte[ ] sb=ka.generateSecret();
            for(int i=0;i<sb.length;i++){
                System.out.print(sb[i]+",");
            }
            SecretKeySpec k=new  SecretKeySpec(sb,"DESede");
        } catch (Exception e) {
            e.printStackTrace();
        }

        String info_ciphertext = new String(ciphertext.getBytes("GBK"),"utf-8");
        //     printWriter.write(info);
        //     printWriter.flush();

        outputStreamWriter.write(info_ciphertext);
        outputStreamWriter.flush();
        socket.shutdownOutput();
        //接收服务器的响应
        String reply = null;
        while (!((reply = bufferedReader.readLine()) ==null)){
            System.out.println("\n" + "接收服务器的信息为：" + reply);
        }
        //4.关闭资源
        bufferedReader.close();
        inputStream.close();
        outputStreamWriter.close();
        //printWriter.close();
        outputStream.close();
        socket.close();
    }
}